package org.chen.ctrip.service.impl;// QdrantHttpService.java
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.chen.common.ctrip.entity.Product;
import org.chen.common.qdrant.QdrantProductData;
import org.chen.ctrip.service.QdrantService;
import org.chen.ctrip.utils.QdrantIdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.util.*;

@Slf4j
@Service
public class QdrantHttpService implements QdrantService {

    @Value("${qdrant.http.host:http://8.219.169.114:6333}")
    private String httpHost;

    @Value("${qdrant.api-key:LZ@nKvnvG6m6gCy}")
    private String apiKey;

    @Value("${qdrant.collection-name:products}")
    private String collectionName;

    @Value("${qdrant.vector-size:384}")
    private int vectorSize;

    @Autowired
    private OllamaEmbeddingService ollamaEmbeddingService;

    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;
    private HttpHeaders headers;

    public QdrantHttpService() {
        this.restTemplate = new RestTemplate();
        this.objectMapper = new ObjectMapper();
    }

    @PostConstruct
    public void init() {
        // 设置HTTP请求头
        headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        if (apiKey != null && !apiKey.isEmpty()) {
            headers.set("api-key", apiKey);
        }

        try {
            initializeCollection(collectionName);
        } catch (Exception e) {
            log.error("初始化Qdrant集合失败", e);
        }
    }

    @Override
    public void initializeCollection(String collectionName) {
        try {
            // 检查集合是否存在
            String url = httpHost + "/collections/" + collectionName;

            try {
                HttpEntity<String> entity = new HttpEntity<>(headers);
                restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
                log.info("Qdrant集合已存在: {}", collectionName);
                return;
            } catch (Exception e) {
                log.info("集合不存在，开始创建: {}", collectionName);
            }

            // 创建集合
            Map<String, Object> createRequest = new HashMap<>();

            Map<String, Object> vectorsConfig = new HashMap<>();
            vectorsConfig.put("size", vectorSize);
            vectorsConfig.put("distance", "Cosine");

            createRequest.put("vectors", vectorsConfig);

            String requestBody = objectMapper.writeValueAsString(createRequest);
            HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);

            ResponseEntity<String> response = restTemplate.exchange(
                    httpHost + "/collections/" + collectionName,
                    HttpMethod.PUT,
                    entity,
                    String.class
            );

            if (response.getStatusCode().is2xxSuccessful()) {
                log.info("成功创建Qdrant集合: {}", collectionName);
            } else {
                log.error("创建Qdrant集合失败: {}", response.getStatusCode());
            }

        } catch (Exception e) {
            log.error("初始化Qdrant集合异常: {}", collectionName, e);
        }
    }

    @Override
    public Object saveProductVector(Product product, String departCityId) {
        if (product == null || product.getId() == null) {
            log.warn("商品数据为空，跳过向量保存");
            throw new RuntimeException("商品数据为空，无法保存向量");
        }

        try {
            // 构建向量数据
            QdrantProductData productData = buildQdrantProductData(product);
            log.info("构建Qdrant商品数据: {}", productData);
            List<Float> vector = generateEmbedding(productData.getContent());

            Object pointId;
            // 转换ID为Qdrant有效格式
            if (departCityId != null) {
                pointId = QdrantIdUtils.toValidPointId(product.getId() + "_" + departCityId);
            } else {
                pointId = QdrantIdUtils.toValidPointId(product.getId());
            }

            // 构建请求数据
            Map<String, Object> point = new HashMap<>();
            point.put("id", pointId);
            point.put("vector", vector);
            Map<String, Object> payload = buildPayloadMap(productData);
            log.info("存到向量数据库的数据：{}", payload);
            point.put("payload", payload);

            Map<String, Object> upsertRequest = new HashMap<>();
            upsertRequest.put("points", Collections.singletonList(point));

            String requestBody = objectMapper.writeValueAsString(upsertRequest);

            // 发送请求
            String url = httpHost + "/collections/" + collectionName + "/points";
            HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);

            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.PUT, entity, String.class);

            if (response.getStatusCode().is2xxSuccessful()) {
//                log.info(response.toString());
                log.info("成功保存商品向量数据: {} -> {}", product.getId(), pointId);
            } else {
                log.error("保存商品向量数据失败: {} - {}", product.getId(), response.getStatusCode());
            }

            return pointId;

        } catch (Exception e) {
            log.error("保存商品向量数据异常: {}", product.getId(), e);
            throw new RuntimeException("保存商品向量数据异常: " + product.getId(), e);
        }
    }

    @Override
    public void deleteProductVector(String productId, String departCityId) {
        try {
            Map<String, Object> deleteRequest = new HashMap<>();

            Object pointId;
            // 转换ID为Qdrant有效格式
            if (departCityId != null) {
                pointId = QdrantIdUtils.toValidPointId(productId + "_" + departCityId);
            } else {
                pointId = QdrantIdUtils.toValidPointId(productId);
            }

            deleteRequest.put("points", Collections.singletonList(pointId));

            String requestBody = objectMapper.writeValueAsString(deleteRequest);

            String url = httpHost + "/collections/" + collectionName + "/points/delete";
            HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);

            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);

            if (response.getStatusCode().is2xxSuccessful()) {
                log.info("成功删除商品向量数据: {}", pointId);
            } else {
                log.error("删除商品向量数据失败: {} - {}", pointId, response.getStatusCode());
            }

        } catch (Exception e) {
            log.error("删除商品向量数据异常: {}", productId, e);
        }
    }


    /**
     * 构建Qdrant商品数据
     */
    private QdrantProductData buildQdrantProductData(Product product) {
        QdrantProductData data = new QdrantProductData();

        data.setContent(product.getPageContent());

        // 构建元数据
        QdrantProductData.QdrantMetadata metadata = new QdrantProductData.QdrantMetadata();
        metadata.setCity(product.getCity());
        metadata.setDurationDays(product.getDurationDays());
        metadata.setTitle(product.getTitle());
        metadata.setProductId(product.getId());
        metadata.setTags(product.getTags());

        data.setMetadata(metadata);
        return data;
    }

    /**
     * 构建载荷Map
     */
    private Map<String, Object> buildPayloadMap(QdrantProductData productData) {
        Map<String, Object> payload = new HashMap<>();

        // 添加内容
        payload.put("content", productData.getContent());

        // 添加元数据
        Map<String, Object> metadata = new HashMap<>();
        QdrantProductData.QdrantMetadata meta = productData.getMetadata();

        if (meta.getCity() != null) {
            metadata.put("city", meta.getCity());
        }
        if (meta.getDurationDays() != null) {
            metadata.put("duration_days", meta.getDurationDays());
        }
        if (meta.getTitle() != null) {
            metadata.put("title", meta.getTitle());
        }
        if (meta.getTags() != null) {
            metadata.put("tags", meta.getTags());
        }
        if (meta.getProductId() != null) {
            metadata.put("product_id", meta.getProductId());
        }

        payload.put("metadata", metadata);
        return payload;
    }

    /**
     * 生成文本嵌入向量 - 使用Ollama bge-m3模型
     */
    private List<Float> generateEmbedding(String text) {
        try {
            // 使用Ollama生成真实的嵌入向量
            List<Float> embedding = ollamaEmbeddingService.generateEmbedding(text);

            if (embedding != null && !embedding.isEmpty()) {
                log.debug("成功生成嵌入向量，维度: {}", embedding.size());
                return embedding;
            } else {
                log.warn("Ollama返回空向量，使用降级方案");
                return generateFallbackVector(text);
            }

        } catch (Exception e) {
            log.error("生成嵌入向量失败，使用降级方案", e);
            return generateFallbackVector(text);
        }
    }

    /**
     * 降级方案：生成确定性随机向量
     */
    private List<Float> generateFallbackVector(String text) {
        List<Float> vector = new ArrayList<>();
        java.util.Random random = new java.util.Random(text.hashCode());
        for (int i = 0; i < vectorSize; i++) {
            vector.add(random.nextFloat() * 2 - 1);
        }
        return vector;
    }
}